package com.jijia.webbase.filter;

import com.jijia.webbase.config.security.SaveLoginUser;
import com.jijia.webbase.utils.JwtUtil;
import com.jijia.webbase.utils.ThreadLocalUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import io.jsonwebtoken.security.SignatureException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;



// JwtAuthFilter.java
// 5. JWT认证过滤器
@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
//        获取请求的url
        String url = request.getRequestURI();
        HashMap<String, Object> threadLocal = new HashMap<>();
        log.debug("JwtAuthenticationFilter过滤器中 url: {}", url);
        if (url.startsWith("/login") || url.startsWith("/register")) {
            filterChain.doFilter(request, response);
            return;
        }
        //从查询字符串获取token
        if (url.startsWith("/chat")) {
            String queryString = request.getQueryString();
            if (queryString.contains("token=")) {
                String token = queryString.split("&")[0].split("=")[1];
                log.debug("过滤器中 token: {}", token);
                if ("null".equals(token)){
                    log.debug("token为空");
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }
                Claims claims = null;
                try {
                    claims = jwtUtil.parseToken(token);
                } catch (ExpiredJwtException e) {
                    log.debug("token已过期");
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                } catch (SignatureException e) {
                    log.debug("token令牌被篡改或过期");
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }
                String username = claims.getSubject();
                log.debug("从token中获取的username: {}", username);
                // 创建Authentication对象
                SaveLoginUser loginUser = jwtUtil.getUser("token_" + username); // 需要从数据库加载或缓存获取
                if (!loginUser.getToken().equals(token)) {
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }
                threadLocal.put("user",loginUser);
                threadLocal.put("validationTokenStatus", true);
                ThreadLocalUtil.set(threadLocal);
                filterChain.doFilter(request, response);
                return;
            }
        }


        // 从请求头获取token
        String cookie = request.getHeader("Cookie");
        if (cookie != null){
            log.debug("从请求头中获取的Cookie: {}", cookie);
            String[] split = cookie.split(";");
            String token = null;
            for (String s : split) {
                if (s.contains("token=")) {
                    token = s.split("=")[1];
                    break;
                }
            }
            log.debug("过滤器中 token: {}", token);
            if (token != null && !token.equals("")) {
                Claims claims = null;
                try {
                    claims = jwtUtil.parseToken(token);
                } catch (ExpiredJwtException e) {
                    log.debug("token已过期");
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }catch (SignatureException e){
                    log.debug("token令牌被篡改或过期");
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }
                String username = claims.getSubject();

                log.debug("从token中获取的username: {}", username);
                // 创建Authentication对象
                SaveLoginUser loginUser = jwtUtil.getUser("token_" + username); // 需要从数据库加载或缓存获取
                if (!loginUser.getToken().equals(token)) {
                    threadLocal.put("validationTokenStatus", false);
                    ThreadLocalUtil.set(threadLocal);
                    filterChain.doFilter(request, response);
                    return;
                }

                log.debug("从redis中获取的loginUser: {}", loginUser);
                threadLocal.put("validationTokenStatus", true);
                threadLocal.put("user",loginUser);
                ThreadLocalUtil.set(threadLocal);
//            List<GrantedAuthority> collect = Arrays.stream(loginUser.getUser().getRoles().split(","))
//                    .map(role -> new SimpleGrantedAuthority("ROLE_" + role))
//                    .collect(Collectors.toList());

//            UsernamePasswordAuthenticationToken authentication =
//                    new UsernamePasswordAuthenticationToken(loginUser, null, collect);
//            SecurityContextHolder.getContext().setAuthentication(authentication);
            } else {
                threadLocal.put("validationTokenStatus", false);
                ThreadLocalUtil.set(threadLocal);
            }
        }else {
            threadLocal.put("validationTokenStatus", false);
            ThreadLocalUtil.set(threadLocal);
        }



        log.debug("向拦截器走");
        filterChain.doFilter(request, response);
    }
}